package com.only4play.codegen.processor.dto;
import com.google.auto.service.AutoService;
import com.only4play.codegen.processor.BaseCodeGenProcessor;
import com.only4play.codegen.processor.CodeGenProcessor;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeSpec.Builder;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import java.lang.annotation.Annotation;
import java.util.Objects;
import java.util.Set;

/**
 * @author mdy
 * vo 代码生成器
 */
@AutoService(value = CodeGenProcessor.class)
public class DtoCodeGenProcessor extends BaseCodeGenProcessor {

  public static final String SUFFIX = "Dto";

  @Override
  public Class<? extends Annotation> getAnnotation() {
    return GenDto.class;
  }

  @Override
  public String generatePackage(TypeElement typeElement) {
    return typeElement.getAnnotation(GenDto.class).pkgName();
  }

  /**
   *
   * @param typeElement 要生成代码的类
   * @param roundEnvironment
   */
  @Override
  protected void generateClass(TypeElement typeElement, RoundEnvironment roundEnvironment) {

    Set<VariableElement> fields = findFields(typeElement,
        ve -> Objects.isNull(ve.getAnnotation(IgnoreDto.class)));
    String className = typeElement.getSimpleName() + SUFFIX;

    Builder builder = TypeSpec.classBuilder(className)
        .addModifiers(Modifier.PUBLIC)
            .addJavadoc("@author mdy")
        .addAnnotation(Schema.class)
        .addAnnotation(Data.class);
    addSetterAndGetterMethod(builder, fields);

//    MethodSpec.Builder constructorSpecBuilder = MethodSpec.constructorBuilder()
//        .addParameter(TypeName.get(typeElement.asType()), "source")
//        .addModifiers(Modifier.PUBLIC);
//
//    constructorSpecBuilder.addStatement("super(source)");
//    fields.stream().forEach(f -> {
//      constructorSpecBuilder.addStatement("this.set$L(source.get$L())", getFieldDefaultName(f),
//          getFieldDefaultName(f));
//    });

    builder.addMethod(MethodSpec.constructorBuilder()
        .addModifiers(Modifier.PROTECTED)
        .build());
//    builder.addMethod(constructorSpecBuilder.build());
    String packageName = generatePackage(typeElement);

    // 不需要经常变化的类可以直接生成的target目录
//    genJavaFile(packageName, builder);
//    genJavaFile(packageName, getSourceTypeWithConstruct(typeElement,sourceClassName, packageName, className));

    // 代码生成到类路径下，第二个入参获取到指定的包路径
    genJavaSourceFile(packageName, typeElement.getAnnotation(GenDto.class).sourcePath(),builder);

  }

  public DtoCodeGenProcessor() {
  }
}
